package com.demo.systemmonitor.utils;

import android.util.Log;
import com.demo.systemmonitor.data.CpuData;
import com.demo.systemmonitor.data.CpuInfo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.Pattern;

/**
 * CPU信息获取工具类，负责从系统文件中读取CPU相关信息
 */
public class CpuUtils {
    private static final String TAG = "CpuUtils";
    private static long lastTotalCpu = 0;
    private static long lastIdleCpu = 0;

    /**
     * 获取CPU静态信息（型号、核心数等）
     */
    public static CpuInfo getCpuInfo() {
        try {
            // 读取CPU型号
            String model = readCpuModel();

            // 获取物理核心数（cpu[0-9]+ 目录数量）
            int cores = getCpuCores();

            // 逻辑处理器数量（可反映超线程）
            int logicalProcessors = getLogicalProcessorCount();

            // 基准频率（max freq）
            String baseSpeed = getMaxCpuFrequency();

            // L1/L2/L3 缓存（若不存在则返回 Unknown）
            String l1 = getCacheSizeByLevel(1);
            String l2 = getCacheSizeByLevel(2);
            String l3 = getCacheSizeByLevel(3);

            // 移动设备通常为单插槽；虚拟化在移动端无实际意义，置为 false
            return new CpuInfo(
                    model,
                    baseSpeed != null ? baseSpeed : "Unknown",
                    1,
                    cores,
                    logicalProcessors,
                    false,
                    l1 != null ? l1 : "Unknown",
                    l2 != null ? l2 : "Unknown",
                    l3 != null ? l3 : "Unknown"
            );
        } catch (Exception e) {
            Log.e(TAG, "获取CPU信息失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 获取CPU实时数据（利用率、频率等）
     */
    public static CpuData getCpuData() {
        try {
            // 获取CPU利用率
            float usage = getCpuUsage();

            // 获取当前CPU频率
            String speed = getCurrentCpuFrequency();
			float frequency = getCpuFrequencyValue(); 

            // 获取进程和线程数量
            int processes = getProcessCount();
            int threads = getTotalThreadCount();
            int handles = -1; // Linux/Android 无统一"句柄"概念，置为不可用

            // 获取CPU温度（摄氏度）
            Float temperatureC = getCpuTemperatureCelsius();

            return new CpuData(usage, speed, frequency, processes, threads, handles, temperatureC);
        } catch (Exception e) {
            Log.e(TAG, "获取CPU实时数据失败: " + e.getMessage());
            return null;
        }
    }

private static float getCpuFrequencyValue() {
    try {
        // 方法1：从 /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 读取
        File freqFile = new File("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq");
        if (freqFile.exists()) {
            BufferedReader reader = new BufferedReader(new FileReader(freqFile));
            String freqStr = reader.readLine();
            reader.close();
            if (freqStr != null) {
                // 文件中的值通常是 kHz，需要转换为 MHz
                return Float.parseFloat(freqStr) / 1000.0f;
            }
        }
        
        // 方法2：从现有的 speed 字符串中解析
        String speed = getCurrentCpuFrequency();
        if (speed != null && speed.contains("MHz")) {
            String freqStr = speed.replace("MHz", "").trim();
            return Float.parseFloat(freqStr);
        }
        
        return 0.0f; // 默认值
    } catch (Exception e) {
        Log.e(TAG, "获取CPU频率失败: " + e.getMessage());
        return 0.0f;
    }
}
    /**
     * 读取CPU型号
     */
    private static String readCpuModel() {
        try {
            BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"));
            String line;
            while ((line = br.readLine()) != null) {
                if (line.contains("model name") || line.contains("Hardware") || line.contains("Processor")) {
                    String[] parts = line.split(": ");
                    if (parts.length >= 2) {
                        br.close();
                        return parts[1].trim();
                    }
                }
            }
            br.close();
        } catch (IOException e) {
            Log.e(TAG, "读取CPU型号失败: " + e.getMessage());
        }
        return "Unknown CPU";
    }

    /**
     * 获取CPU核心数
     */
    private static int getCpuCores() {
        try {
            File[] files = new File("/sys/devices/system/cpu/").listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return Pattern.matches("cpu[0-9]+", pathname.getName());
                }
            });
            return files != null ? files.length : 1;
        } catch (Exception e) {
            Log.e(TAG, "获取CPU核心数失败: " + e.getMessage());
            return 1;
        }
    }

    /**
     * 获取逻辑处理器数量
     */
    private static int getLogicalProcessorCount() {
        try {
            return Runtime.getRuntime().availableProcessors();
        } catch (Exception e) {
            return getCpuCores();
        }
    }

    /**
     * 计算CPU利用率
     */
    private static float getCpuUsage() {
        try {
            BufferedReader br = new BufferedReader(new FileReader("/proc/stat"));
            String line = br.readLine();
            br.close();

            if (line != null && line.startsWith("cpu ")) {
                String[] parts = line.split("\\s+");
                long user = Long.parseLong(parts[1]);
                long nice = Long.parseLong(parts[2]);
                long system = Long.parseLong(parts[3]);
                long idle = Long.parseLong(parts[4]);
                long iowait = Long.parseLong(parts[5]);
                long irq = Long.parseLong(parts[6]);
                long softirq = Long.parseLong(parts[7]);

                long total = user + nice + system + idle + iowait + irq + softirq;
                long work = total - idle;

                // 首次调用不计算，仅初始化
                if (lastTotalCpu == 0 || lastIdleCpu == 0) {
                    lastTotalCpu = total;
                    lastIdleCpu = idle;
                    return 0;
                }

                // 计算CPU利用率
                long totalDiff = total - lastTotalCpu;
                long workDiff = work - (lastTotalCpu - lastIdleCpu);
                float usage = (totalDiff > 0) ? (float) workDiff / totalDiff * 100 : 0;

                // 更新上次值
                lastTotalCpu = total;
                lastIdleCpu = idle;

                return usage;
            }
        } catch (IOException e) {
            Log.e(TAG, "计算CPU利用率失败: " + e.getMessage());
        }
        return 0;
    }

    /**
     * 获取当前CPU频率
     */
    private static String getCurrentCpuFrequency() {
        try {
            // 读取第一个CPU核心的当前频率
            BufferedReader br = new BufferedReader(new FileReader(
                    "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"));
            String freqStr = br.readLine();
            br.close();

            if (freqStr != null) {
                long freqKhz = Long.parseLong(freqStr);
                // 转换为GHz或MHz
                if (freqKhz >= 1000000) {
                    return String.format("%.2f GHz", freqKhz / 1000000.0);
                } else {
                    return String.format("%d MHz", freqKhz / 1000);
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "获取CPU频率失败: " + e.getMessage());
        }
        return "Unknown";
    }

    /**
     * 获取最大CPU频率（基准速度近似）
     */
    private static String getMaxCpuFrequency() {
        String[] candidates = new String[]{
                "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq",
                "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"
        };
        for (String path : candidates) {
            try {
                BufferedReader br = new BufferedReader(new FileReader(path));
                String freqStr = br.readLine();
                br.close();
                if (freqStr != null) {
                    long freqKhz = Long.parseLong(freqStr.trim());
                    if (freqKhz >= 1000000) {
                        return String.format("%.2f GHz", freqKhz / 1000000.0);
                    } else if (freqKhz > 0) {
                        return String.format("%d MHz", freqKhz / 1000);
                    }
                }
            } catch (Exception ignored) {
            }
        }
        return null;
    }

    /**
     * 读取缓存大小（Level 1/2/3）
     */
    private static String getCacheSizeByLevel(int level) {
        // Android 上 cpu0 缓存信息位于：/sys/devices/system/cpu/cpu0/cache/indexX/size
        // 常见映射：index0:L1d, index1:L1i, index2:L2, index3:L3（可能不存在）
        int[] indexCandidates;
        if (level == 1) {
            indexCandidates = new int[]{0, 1}; // L1d 或 L1i
        } else if (level == 2) {
            indexCandidates = new int[]{2};
        } else if (level == 3) {
            indexCandidates = new int[]{3};
        } else {
            return null;
        }
        List<String> parts = new ArrayList<>();
        for (int idx : indexCandidates) {
            String path = "/sys/devices/system/cpu/cpu0/cache/index" + idx + "/size";
            try {
                BufferedReader br = new BufferedReader(new FileReader(path));
                String size = br.readLine();
                br.close();
                if (size != null && !size.isEmpty()) {
                    parts.add(size.trim());
                }
            } catch (Exception ignored) {
            }
        }
        if (parts.isEmpty()) return null;
        if (parts.size() == 1) return parts.get(0);
        // L1 合并显示：如 "32K + 32K"
        return TextUtilsJoin(parts, " + ");
    }

    private static String TextUtilsJoin(List<String> list, String sep) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            if (i > 0) sb.append(sep);
            sb.append(list.get(i));
        }
        return sb.toString();
    }

    /**
     * 获取当前进程数量
     */
    private static int getProcessCount() {
        try {
            File[] processes = new File("/proc/").listFiles(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    try {
                        Integer.parseInt(file.getName());
                        return true;
                    } catch (NumberFormatException e) {
                        return false;
                    }
                }
            });
        	return processes != null ? processes.length : 0;
        } catch (Exception e) {
            Log.e(TAG, "获取进程数量失败: " + e.getMessage());
            return 0;
        }
    }

    /**
     * 统计系统总线程数（遍历 /proc/<pid>/status 的 Threads 字段）
     */
    private static int getTotalThreadCount() {
        int totalThreads = 0;
        try {
            File[] processes = new File("/proc/").listFiles(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    try {
                        Integer.parseInt(file.getName());
                        return true;
                    } catch (NumberFormatException e) {
                        return false;
                    }
                }
            });
            if (processes == null) return 0;
            for (File pidDir : processes) {
                File status = new File(pidDir, "status");
                if (!status.exists()) continue;
                try (BufferedReader br = new BufferedReader(new FileReader(status))) {
                    String line;
                    while ((line = br.readLine()) != null) {
                        if (line.startsWith("Threads:")) {
                            String[] parts = line.split("\\s+");
                            if (parts.length >= 2) {
                                totalThreads += Integer.parseInt(parts[1]);
                            }
                            break;
                        }
                    }
                } catch (Exception ignored) {
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "统计线程数量失败: " + e.getMessage());
        }
        return totalThreads;
    }

    /**
     * 读取 CPU 温度（摄氏度）。
     * 优先读取固定路径 /sys/devices/virtual/thermal/thermal_zone0/temp；
     * 若不可用，再尝试 thermal/hwmon 兼容路径。
     */
    private static Float getCpuTemperatureCelsius() {
        // 优先：你所提供的路径（毫摄氏度，示例 48000）
        Float fromFixed = readTemperatureFromFile("/sys/devices/virtual/thermal/thermal_zone0/temp");
        if (fromFixed != null) return fromFixed;
        // 回退：thermal zones
        Float t = readThermalZones();
        if (t != null) return t;
        // 回退：hwmon
        t = readHwmon();
        if (t != null) return t;
        return null;
    }

    private static Float readThermalZones() {
        File dir = new File("/sys/class/thermal/");
        File[] zones = dir.listFiles();
        if (zones == null) return null;
        for (File z : zones) {
            if (!z.getName().startsWith("thermal_zone")) continue;
            File typeFile = new File(z, "type");
            String type = readFirstLine(typeFile);
            if (type == null) continue;
            String lower = type.toLowerCase();
            if (!(lower.contains("cpu") || lower.contains("soc") || lower.contains("ap") || lower.contains("tsens"))) {
                continue;
            }
            File tempFile = new File(z, "temp");
            Float v = readTemperatureFromFile(tempFile.getPath());
            if (v != null) return v;
        }
        return null;
    }

    private static Float readHwmon() {
        File dir = new File("/sys/class/hwmon/");
        File[] hwmons = dir.listFiles();
        if (hwmons == null) return null;
        for (File h : hwmons) {
            for (int i = 1; i <= 5; i++) {
                File f = new File(h, "temp" + i + "_input");
                Float v = readTemperatureFromFile(f.getPath());
                if (v != null) return v;
            }
        }
        return null;
    }

    private static String readFirstLine(File file) {
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            return br.readLine();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 支持 3 种单位：摄氏度、毫摄氏度(如 37500)、微摄氏度(如 37500000)。
     */
    private static Float readTemperatureFromFile(String path) {
        try (BufferedReader br = new BufferedReader(new FileReader(path))) {
            String s = br.readLine();
            if (s == null) return null;
            s = s.trim();
            if (s.isEmpty()) return null;
            if (s.contains(".")) {
                return Float.parseFloat(s);
            }
            long v = Long.parseLong(s);
            if (v > 1000_000) {
                return v / 1_000_000f;
            } else if (v > 1000) {
                return v / 1000f;
            } else {
                return (float) v;
            }
        } catch (Exception e) {
            return null;
        }
    }
}
